package com.jy.modules.cims.common.sysUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @description 日期时间工具类
 * @version v1.0
 * @author ShengZhoutao
 * @Date 2012-9-27
 */
public final class DateTimeUtils {

	/**
	 * 缺省的日期显示格式： yyyyMMdd
	 */
	public static final String DEFAULT_DATE_FORMAT = "yyyyMMdd";
	public static final String DEFAULT_DATE_FORMAT_2 = "yyyy-MM-dd";
	public static final String DEFAULT_DATE_FORMAT_3 = "yyyy/MM/dd";
	public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DEFAULT_DATE_TIME_FORMAT_2 = "yyyyMMddHHmmss";
	public static final String DEFAULT_DATE_TIME_FORMAT_3 = "yyyy/MM/dd HH/mm/ss";
	
	/**
	 * 获取当前日期时间
	 * 
	 * @param format
	 * @return
	 */
	public static String getDateTime(String format) {
		Date dt = new Date();
		return formatDate(dt, format);
	}

	/**
	 * 格式化日期时间为指定格式的字符串
	 * 
	 * @param format
	 * @return
	 */
	public static String formatDate(Date dt, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(dt);
	}

	/**
	 * 解析字符串转为Date
	 * 
	 * @param dateStr
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static Date parseDate(String dateStr, String format)
			throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.parse(dateStr);
	}

	/**
	 * 日期时间比较，若d1大于d2，则返回true
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static Boolean dateCompare(Date d1, Date d2) {
		if (d1.getTime() > d2.getTime()) {
			return true;
		}
		return false;
	}

	/**
	 * 日期时间比较，若d1大于d2，则返回true
	 * 
	 * @param d1
	 * @param d2
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static Boolean dateCompare(String d1, String d2, String format)
			throws ParseException {
		SimpleDateFormat sf = new SimpleDateFormat(format);
		Date date1 = sf.parse(d1);
		Date date2 = sf.parse(d2);
		return dateCompare(date1, date2);
	}

	/**
	 * 计算当前时间后延一段时间之后的时间点
	 * 
	 * @param minute
	 *            单位为分钟
	 * @param format
	 * @return
	 */
	public static String calDateStr(int minute, String format) {
		Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		return formatter.format(new Date(date.getTime() + minute * 60 * 1000));// 初始化时间为当前系统时间+1
	}

	/**
	 * 计算当前时间后延一段时间之后的时间点
	 * 
	 * @param minute
	 *            单位为分钟
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static String calDateStr(String dateStr, int minute, String format)
			throws ParseException {
		// yyyyMMddHHmmss
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		Date date = formatter.parse(dateStr);

		return formatter.format(new Date(date.getTime() + minute * 60 * 1000));// 初始化时间为当前系统时间+1
	}

	/**
	 * 检查日期字符串是否符合格式定义
	 * 
	 * @param dateStr
	 * @param format
	 * @return
	 */
	public static Boolean checkPattern(String dateStr, String format) {
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		try {
			formatter.parse(dateStr);
		} catch (ParseException e) {
			return false;
		}
		return true;
	}

	/**
	 * 取得指定日期以后某月某日的日期。如果要得到以前的日期，参数用负数。
	 * 
	 * @param date
	 *            基准日期
	 * @param hours
	 *            增加的小时数
	 * @return 增加以后的日期
	 */
	public static Date addHours(Date date, int hours) {
		return add(date, hours, Calendar.HOUR);
	}
	
	/**
	 * 取得指定日期以后若干天的日期。如果要得到以前的日期，参数用负数。
	 * 
	 * @param date
	 *            基准日期
	 * @param days
	 *            增加的日期数
	 * @return 增加以后的日期
	 */
	public static Date addDays(Date date, int days) {
		return add(date, days, Calendar.DATE);
	}

	/**
	 * 取得指定日期以后某月的日期。如果要得到以前月份的日期，参数用负数。 注意，可能不是同一日子，例如2003-1-31加上一个月是2003-2-28
	 * 
	 * @param date
	 *            基准日期
	 * @param months
	 *            增加的月份数
	 * @return 增加以后的日期
	 */
	public static Date addMonths(Date date, int months) {
		return add(date, months, Calendar.MONTH);
	}

	/**
	 * @param date
	 *            基准日期
	 * @param years
	 *            增加的年数
	 * @return 增加以后的日期
	 */
	public static Date addYears(Date date, int years) {
		return add(date, years, Calendar.YEAR);
	}

	/**
	 * 内部方法。为指定日期增加相应的天数或月数
	 * 
	 * @param date
	 *            基准日期
	 * @param amount
	 *            增加的数量
	 * @param field
	 *            增加的单位，年，月或者日
	 * @return 增加以后的日期
	 */
	public static Date add(Date date, int amount, int field) {
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(date);
		calendar.add(field, amount);

		return calendar.getTime();
	}

	/**
	 * 计算两个日期相差天数。 用第一个日期减去第二个。如果前一个日期小于后一个日期，则返回负数
	 * 
	 * @param one
	 *            第一个日期数，作为基准
	 * @param two
	 *            第二个日期数，作为比较
	 * @return 两个日期相差天数
	 */
	public static Long diffDays(Date one, Date two) {
		return (one.getTime() - two.getTime()) / (24 * 60 * 60 * 1000);
	}

	/**
	 * 计算两个日期相差月份数 如果前一个日期小于后一个日期，则返回负数
	 * 
	 * @param one
	 *            第一个日期数，作为基准
	 * @param two
	 *            第二个日期数，作为比较
	 * @return 两个日期相差月份数
	 */
	public static Integer diffMonths(Date one, Date two) {
		Calendar calendar = Calendar.getInstance();

		// 得到第一个日期的年分和月份数
		calendar.setTime(one);
		int yearOne = calendar.get(Calendar.YEAR);
		int monthOne = calendar.get(Calendar.MONDAY);

		// 得到第二个日期的年份和月份
		calendar.setTime(two);
		int yearTwo = calendar.get(Calendar.YEAR);
		int monthTwo = calendar.get(Calendar.MONDAY);

		return (yearOne - yearTwo) * 12 + (monthOne - monthTwo);
	}

	/**
	 * 将一个字符串用给定的格式转换为日期类型。<br>
	 * 注意：如果返回null，则表示解析失败
	 * 
	 * @param datestr
	 *            需要解析的日期字符串
	 * @param pattern
	 *            日期字符串的格式，默认为“yyyyMMdd”的形式
	 * @return 解析后的日期
	 */
	public static Date parse(String datestr, String pattern) {
		Date date = null;

		if (null == pattern || "".equals(pattern)) {
			pattern = DEFAULT_DATE_FORMAT;
		}

		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
			date = dateFormat.parse(datestr);
		} catch (ParseException e) {
			//
		}

		return date;
	}

	/**
	 * 返回给定日期中的月份中的最后一天
	 * 
	 * @param date
	 *            基准日期
	 * @return 该月最后一天的日期
	 */
	public static Date getMonthLastDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		// 将日期设置为下一月第一天
		calendar.set(calendar.get(Calendar.YEAR),
				calendar.get(Calendar.MONTH) + 1, 1);

		// 减去1天，得到的即本月的最后一天
		calendar.add(Calendar.DATE, -1);

		return calendar.getTime();
	}

	/**
	 * 返回给定日期中的本年最后一月中的最后一天
	 * 
	 * @param date
	 *            基准日期
	 * @return 本年最后一月中的最后一天
	 */
	public static Date getLastMonthLastDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		calendar.set(calendar.get(Calendar.YEAR), 11, 31);
		return calendar.getTime();
	}

	/**
	 * 返回给定日期中的月份中的第一天
	 * 
	 * @param date
	 *            基准日期
	 * @return 该月第一天的日期
	 */
	public static Date getMonthFirstDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		// 将日期设置为本月第一天
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
				1);

		return calendar.getTime();
	}

	/**
	 * 此方法计算时间毫秒
	 * 
	 * @param inVal
	 * @param inVal2
	 * @return
	 * @throws Exception
	 */
	public static Long getDateDiff(Long inVal, Long inVal2) throws Exception {
		Date date = null; // 定义时间类型
		Date date1 = null; // 定义时间类型
		SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-mm-dd");
		try {
			date = inputFormat.parse(inVal.toString()); // 将字符型转换成日期型
			date1 = inputFormat.parse(inVal2.toString()); // 将字符型转换成日期型
			return (Long) (date.getTime() - date1.getTime()) / 1000 / 3600 / 24; // 返回天数
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 计算两个时间的相差毫秒数
	 * 
	 * @param d1
	 * @param d2
	 * @return
	 * @throws ParseException
	 */
	public static long secondDiff(long d1, long d2) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("hhmmss");
		Date date1 = sdf.parse(String.valueOf(d1));
		Date date2 = sdf.parse(String.valueOf(d2));

		return date1.getTime() - date2.getTime() / 1000;

	}

	/**
	 * 
	 * @param calendar
	 * @return
	 */
	public static String formatTime(Calendar calendar) {
		int hour = 0;
		int minute = 0;
		int second = 0;

		second = (int) calendar.getTimeInMillis() / 1000;
		if (second > 60) {
			minute = second / 60;
			second = second % 60;
		}
		if (minute > 60) {
			hour = minute / 60;
			minute = minute % 60;
		}
		return String.format("%02d:%02d:%02d", hour, minute, second);
	}

	/**
	 * 获取指定日期所在周的周一
	 * 
	 * @Methods Name getMonday
	 * @return Date
	 */
	public Date getMonday(Date date) {
		Calendar cDay = Calendar.getInstance();
		cDay.setTime(date);
		cDay.set(Calendar.DAY_OF_WEEK, 2);// 老外将周日定位第一天，周一取第二天
		return cDay.getTime();
	}

	/**
	 * 获取指定日期所在周日
	 * 
	 * @Methods Name getSunday
	 * @return Date
	 */
	public Date getSunday(Date date) {
		Calendar cDay = Calendar.getInstance();
		cDay.setTime(date);
		if (Calendar.DAY_OF_WEEK == cDay.getFirstDayOfWeek()) { // 如果刚好是周日，直接返回
			return date;
		} else {// 如果不是周日，加一周计算
			cDay.add(Calendar.DAY_OF_YEAR, 7);
			cDay.set(Calendar.DAY_OF_WEEK, 1);
			return cDay.getTime();
		}
	}

	/**
	 * 得到本月第一天的日期
	 * 
	 * @Methods Name getFirstDayOfMonth
	 * @return Date
	 */
	public Date getFirstDayOfMonth(Date date) {
		Calendar cDay = Calendar.getInstance();
		cDay.setTime(date);
		cDay.set(Calendar.DAY_OF_MONTH, 1);
		return cDay.getTime();
	}

	/**
	 * 得到本月最后一天的日期
	 * 
	 * @Methods Name getLastDayOfMonth
	 * @return Date
	 */
	public static Date getLastDayOfMonth(Date date) {
		Calendar cDay = Calendar.getInstance();
		cDay.setTime(date);
		cDay.set(Calendar.DAY_OF_MONTH,
				cDay.getActualMaximum(Calendar.DAY_OF_MONTH));
		return cDay.getTime();
	}

	/**
	 * 得到本季度第一天的日期
	 * 
	 * @Methods Name getFirstDayOfQuarter
	 * @return Date
	 */
	public static Date getFirstDayOfQuarter(Date date) {
		Calendar cDay = Calendar.getInstance();
		cDay.setTime(date);
		int curMonth = cDay.get(Calendar.MONTH);
		if (curMonth >= Calendar.JANUARY && curMonth <= Calendar.MARCH) {
			cDay.set(Calendar.MONTH, Calendar.JANUARY);
		}
		if (curMonth >= Calendar.APRIL && curMonth <= Calendar.JUNE) {
			cDay.set(Calendar.MONTH, Calendar.APRIL);
		}
		if (curMonth >= Calendar.JULY && curMonth <= Calendar.SEPTEMBER) {
			cDay.set(Calendar.MONTH, Calendar.JULY);
		}
		if (curMonth >= Calendar.OCTOBER && curMonth <= Calendar.DECEMBER) {
			cDay.set(Calendar.MONTH, Calendar.OCTOBER);
		}
		cDay.set(Calendar.DAY_OF_MONTH,
				cDay.getActualMinimum(Calendar.DAY_OF_MONTH));
		return cDay.getTime();
	}

	/**
	 * 得到本季度最后一天的日期
	 * 
	 * @Methods Name getLastDayOfQuarter
	 * @return Date
	 */
	public static Date getLastDayOfQuarter(Date date) {
		Calendar cDay = Calendar.getInstance();
		cDay.setTime(date);
		int curMonth = cDay.get(Calendar.MONTH);
		if (curMonth >= Calendar.JANUARY && curMonth <= Calendar.MARCH) {
			cDay.set(Calendar.MONTH, Calendar.MARCH);
		}
		if (curMonth >= Calendar.APRIL && curMonth <= Calendar.JUNE) {
			cDay.set(Calendar.MONTH, Calendar.JUNE);
		}
		if (curMonth >= Calendar.JULY && curMonth <= Calendar.SEPTEMBER) {
			cDay.set(Calendar.MONTH, Calendar.SEPTEMBER);
		}
		if (curMonth >= Calendar.OCTOBER && curMonth <= Calendar.DECEMBER) {
			cDay.set(Calendar.MONTH, Calendar.DECEMBER);
		}
		cDay.set(Calendar.DAY_OF_MONTH,
				cDay.getActualMaximum(Calendar.DAY_OF_MONTH));

		return cDay.getTime();
	}

	/**
	 * 得到一段时间的所有的日期
	 * 
	 * @Methods Name getBetweenDate
	 * @return List<Date>
	 */
	public static List<Date> getBetweenDate(Date startDate, Date endDate) {
		if (null == startDate || null == endDate) {
			return null;
		}

		List<Date> dateList = new ArrayList<Date>();

		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(startDate);

		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDate);

		while ((endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis()) >= 0) {
			dateList.add(startCalendar.getTime());
			startCalendar.setTimeInMillis(startCalendar.getTimeInMillis() + 24
					* 60 * 60 * 1000);
		}

		return dateList;
	}
	
	/** 
     * 获取指定月的前一月（年）或后一月（年） 
     * @param dateStr 
     * @param addYear 
     * @param addMonth 
     * @param addDate 
     * @return 输入的时期格式为yyyy-MM，输出的日期格式为yyyy-MM 
     * @throws Exception 
     */  
    public static String getLastMonth(String dateStr,int addYear, int addMonth, int addDate) throws Exception {  
          try {  
          java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM");  
          java.util.Date sourceDate = sdf.parse(dateStr);  
          Calendar cal = Calendar.getInstance();  
          cal.setTime(sourceDate);  
          cal.add(Calendar.YEAR,addYear);  
          cal.add(Calendar.MONTH, addMonth);  
          cal.add(Calendar.DATE, addDate);  

          java.text.SimpleDateFormat returnSdf = new java.text.SimpleDateFormat("yyyy-MM");  
          String dateTmp = returnSdf.format(cal.getTime());  
          //java.util.Date returnDate = returnSdf.parse(dateTmp);  
          return dateTmp;  
          } catch (Exception e) {  
          e.printStackTrace();  
          throw new Exception(e.getMessage());  
          }  
    }
    
    /**
     * 获取当前日期的年月日时分秒，但是时分秒统一进行格式处理00:00:00， 格式如下：yyyy-MM-dd 00:00:00
     * 返回结果字符串
     * */
    public static String getCurrentDateYMDHMS(Date date){
    	return DateTimeUtils.formatDate(date, DateTimeUtils.DEFAULT_DATE_TIME_FORMAT).substring(0, 10) + " 00:00:00";
    }
    
    /**
     * 
     * @author zhangmi
     * @date  2017年5月9日
     * @return
     */
    public static Date GetYesterDay(){
    	Calendar cal=Calendar.getInstance();
    	//System.out.println(Calendar.DATE);//5
    	cal.add(Calendar.DATE,-1);
    	Date time=cal.getTime();
    	return time;
    }
}